<template>
  <div class="chart-wrapper">
    <div :style="{ height: chartConfig.height + 'px' }" :id="chartId" class="chart"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  name: 'RadarChart',
  props: {
    /**
     * 图表标题
     * @example '能力评估分析'
     */
    title: {
      type: String,
      default: '',
    },

    /**
     * 雷达图指标配置
     * @description 定义雷达图的各个维度
     * @example [{ name: '技能1', max: 100 }]
     */
    indicators: {
      type: Array,
      required: true,
    },

    /**
     * 当前值数据
     * @description 当前系列的数据值
     * @example [80, 90, 70]
     */
    values: {
      type: Array,
      required: true,
    },

    /**
     * 目标值数据
     * @description 目标系列的数据值
     * @example [90, 95, 85]
     */
    targetValues: {
      type: Array,
      required: true,
    },

    /**
     * 图表配置项
     * @description 图表的详细配置，包括雷达图样式、图例等
     */
    chartConfig: {
      type: Object,
      default: () => ({
        height: 400,
        // 图例配置
        legend: {
          show: true,
          data: ['当前值', '目标值'],
          bottom: 0,
          textStyle: {
            color: '#333',
            fontSize: 12,
          },
        },
        // 雷达图配置
        radar: {
          shape: 'polygon',
          splitNumber: 5,
          center: ['50%', '50%'],
          radius: '65%',
          axisName: {
            color: '#333',
            fontSize: 12,
            padding: [0, 15, 0, 0],
            formatter: text => text + '\n',
          },
          splitArea: {
            show: true,
            areaStyle: {
              color: ['rgba(255, 255, 255, 0.5)'],
              shadowColor: 'rgba(0, 0, 0, 0.2)',
              shadowBlur: 10,
            },
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: '#ddd',
            },
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: '#ddd',
            },
          },
        },
        // 系列配置
        series: {
          current: {
            name: '当前值',
            color: '#91cc75',
            areaStyle: {
              opacity: 0.3,
              color: 'rgba(145, 204, 117, 0.3)',
            },
            label: {
              show: true,
              formatter: '{c}',
              position: 'top',
            },
          },
          target: {
            name: '目标值',
            color: '#5470c6',
            areaStyle: {
              opacity: 0.3,
              color: 'rgba(84, 112, 198, 0.3)',
            },
            label: {
              show: true,
              formatter: '{c}',
              position: 'top',
            },
          },
        },
      }),
    },

    /**
     * PPT导出配置
     * @description PPT导出时的样式和布局配置
     */
    pptOptions: {
      type: Object,
      default: () => ({
        // 图表位置和大小
        position: {
          x: 0,
          y: 1,
          w: 4.5,
          h: 4.5,
        },
        // 标题配置
        title: {
          x: 0.5,
          y: 1.2,
          fontSize: 16,
          color: '363636',
          bold: true,
        },
        // 图表配置
        chart: {
          showLegend: true,
          legendPos: 'b',
          radarStyle: 'filled',
          chartColorsOpacity: 25,
          catAxisLabelFontBold: true,
          catAxisHidden: false,
          catAxisLabelFontSize: 10,
          catAxisLabelColor: '000000',
          valAxisHidden: true,
        },
      }),
    },
  },

  data() {
    return {
      // echarts实例
      chart: null,
      // 图表唯一标识
      chartId: Math.random().toString(36).substring(2, 15),
    };
  },

  methods: {
    /**
     * 初始化图表
     * @description 创建echarts实例并首次渲染
     */
    initChart() {
      const chartDom = document.getElementById(this.chartId);
      if (!chartDom) return;

      this.chart = echarts.init(chartDom);
      this.updateChart();
    },

    /**
     * 更新图表数据和配置
     * @description 根据props更新图表的数据和配置项
     */
    updateChart() {
      if (!this.chart) return;

      const option = {
        legend: this.chartConfig.legend,
        radar: {
          ...this.chartConfig.radar,
          indicator: this.indicators,
        },
        series: [
          {
            type: 'radar',
            data: [
              {
                ...this.chartConfig.series.current,
                value: this.values,
                itemStyle: { color: this.chartConfig.series.current.color },
              },
              {
                ...this.chartConfig.series.target,
                value: this.targetValues,
                itemStyle: { color: this.chartConfig.series.target.color },
              },
            ],
          },
        ],
      };

      this.chart.setOption(option);
    },

    /**
     * 调整图表大小
     * @description 在容器大小变化时自动调整图表大小
     */
    resizeChart() {
      this.chart && this.chart.resize();
    },

    /**
     * 导出为PPT
     * @description 将图表导出为PPT格式
     * @param {Object} pptx pptxgen实例
     * @param {Object} slide 当前幻灯片实例
     */
    exportToPPT(pptx, slide) {
      // 添加图表标题
      slide.addText(this.title, {
        x: this.pptOptions.title.x,
        y: this.pptOptions.title.y,
        fontSize: this.pptOptions.title.fontSize,
        color: this.pptOptions.title.color,
        bold: this.pptOptions.title.bold,
      });
      // 添加雷达图
      slide.addChart(
        pptx.ChartType.radar,
        [
          {
            name: this.chartConfig.series.current.name,
            labels: this.indicators.map(item => item.name),
            values: this.values,
          },
          {
            name: this.chartConfig.series.target.name,
            labels: this.indicators.map(item => item.name),
            values: this.targetValues,
          },
        ],
        {
          x: this.pptOptions.position.x,
          y: this.pptOptions.position.y,
          w: this.pptOptions.position.w,
          h: this.pptOptions.position.h,
          chartColors: [this.chartConfig.series.current.color.replace('#', ''), this.chartConfig.series.target.color.replace('#', '')],
          showLegend: this.pptOptions.chart.showLegend,
          legendPos: this.pptOptions.chart.legendPos,
          radarStyle: this.pptOptions.chart.radarStyle,
          chartColorsOpacity: this.pptOptions.chart.chartColorsOpacity,
          catAxisLabelFontBold: this.pptOptions.chart.catAxisLabelFontBold,
          catAxisHidden: this.pptOptions.chart.catAxisHidden,
          catAxisLabelFontSize: this.pptOptions.chart.catAxisLabelFontSize,
          catAxisLabelColor: this.pptOptions.chart.catAxisLabelColor,
          valAxisHidden: this.pptOptions.chart.valAxisHidden,
          valAxisMaxVal: Math.max(...this.values, ...this.targetValues) + 30,
        }
      );
    },
  },

  watch: {
    /**
     * 监听数据变化
     * @description 当数据变化时自动更新图表
     */
    values: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
    targetValues: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
    indicators: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
    chartConfig: {
      handler() {
        this.updateChart();
      },
      deep: true,
    },
  },

  mounted() {
    this.$nextTick(() => {
      this.initChart();
      window.addEventListener('resize', this.resizeChart);
    });
  },

  beforeDestroy() {
    window.removeEventListener('resize', this.resizeChart);
    this.chart && this.chart.dispose();
    this.chart = null;
  },
};
</script>

<style lang="less" scoped>
.chart-wrapper {
  width: 100%;
  .chart {
    width: 100%;
  }
}
</style>
